//package com.zmn.plat.admin.aspect;
//
//import com.alibaba.nacos.common.utils.Md5Utils;
//import com.zmn.common.dto2.ResponseDTO;
//import com.zmn.common.utils.string.StringUtil;
//import com.zmn.manager.redis.lock.DistributedLock;
//import com.zmn.manager.redis.lock.DistributedLockUtils;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.springframework.data.redis.core.RedisTemplate;
//import org.springframework.data.redis.core.ValueOperations;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
//import javax.annotation.Resource;
//import javax.servlet.http.HttpServletRequest;
//import java.util.Objects;
//import java.util.concurrent.TimeUnit;
//import java.util.stream.Stream;
//
///**
// * 描述: 防止3秒内数据重复提交
// *
// * @author guoqiao
// * @since 2021/6/28 14:02
// */
//@Slf4j
//@Aspect
//@Component
//public class RepeatSubmitAspect {
//
//    private static final String REDIS_REPEAT_SUBMIT_KEY = "repeat:submit:";
//
//    private static final String LOCK = "lock:";
//
//    // 过期时间(秒)
//    private static final int LOCK_TIME_OUT = 15;
//
//    private static final int CACHE_TIME_OUT = 3;
//
//    @Resource
//    RedisTemplate<String, String> redisTemplate;
//
//    /**
//     * 设定切入点
//     */
//    @Pointcut(value = "@annotation(com.zmn.plat.admin.aspect.RepeatSubmit)")
//    private void pointCutMethod() {
//    }
//
//    @Around(value = "pointCutMethod() && @annotation(repeatSubmit)")
//    public Object checkSign(ProceedingJoinPoint joinPoint, RepeatSubmit repeatSubmit) throws Throwable {
//
//        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
//        String urlMd5 = Md5Utils.getMD5(request.getRequestURL().toString().getBytes());
//        Object[] arguments = joinPoint.getArgs();
//        Object o = Stream.of(arguments).findFirst().orElse(null);
//        if (Objects.isNull(o)) {
//            log.error("[{防止3秒内数据重复提交}],获取参数为null,msg：{null}");
//            return joinPoint.proceed();
//        }
//        String prmMd5 = Md5Utils.getMD5(o.toString().getBytes());
//        String redisKey = REDIS_REPEAT_SUBMIT_KEY + urlMd5;
//
//        String lockKey = LOCK + redisKey;
//        DistributedLock lock = DistributedLockUtils.build(lockKey, LOCK_TIME_OUT);
//        try {
//            if (lock.tryLock()) {
//                ValueOperations<String, String> redisOpsValue = redisTemplate.opsForValue();
//                String cachePrmMd5 = redisOpsValue.get(redisKey);
//                if (StringUtil.isNotBlank(cachePrmMd5) && Objects.equals(cachePrmMd5, prmMd5)) {
//                    return ResponseDTO.fail("重复提交,3秒后重试！");
//                }
//                redisOpsValue.set(redisKey, prmMd5, CACHE_TIME_OUT, TimeUnit.SECONDS);
//            }
//        } catch (Exception e) {
//            log.error("[{aop 防止3秒内数据重复提交}],防止重复提交失败,msg：{}", e.getMessage(), e);
//            throw new RuntimeException(e.getMessage(), e);
//        } finally {
//            lock.unlock();
//        }
//        return joinPoint.proceed();
//    }
//
//}
